package com.yingwei.${pojo.getMetaAsString("project_name")}.swing;

<#assign hasSet = false >

<#foreach field in pojo.getAllPropertiesIterator()>
<#if pojo.getJavaTypeName(field,false).equals("Set")>
	<#assign hasSet = true >
	<#assign SetClassName = pojo.beanCapitalize(field.name) >
	<#assign field1 = field >
</#if>
</#foreach>

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yingwei.${pojo.getMetaAsString("project_name")}.control.Data;
import com.yingwei.${pojo.getMetaAsString("project_name")}.model.businessobject.${pojo.getDeclarationName()};
<#foreach field in pojo.getAllPropertiesIterator()>
<#if (field.type.toString().indexOf("ManyToOneType") > 0) >
import com.yingwei.${pojo.getMetaAsString("project_name")}.model.businessobject.${pojo.getJavaTypeName(field,false)};
</#if>
</#foreach>
import com.yingwei.util.DateRenderer;

@SuppressWarnings("serial")
/**
 * This class needs to access message bundle properties:
 * add_new_${pojo.getDeclarationName()}, delete_${pojo.getDeclarationName()}, refresh_${pojo.getDeclarationName()}
 * ${pojo.getDeclarationName()}_management
 * 
 */
public class ${pojo.getDeclarationName()}TableList extends JPanel
{
    private static Logger logger = LoggerFactory.getLogger(${pojo.getDeclarationName()}TableList.class);
    private static Locale currentLocale = Locale.CHINA;
    private static ResourceBundle bundle = ResourceBundle.getBundle("MessagesBundle", Locale.CHINA);
    Data data;
    MyTableModel myModel = new MyTableModel();

    public ${pojo.getDeclarationName()}TableList()
    {
		super(new BorderLayout());
		setPreferredSize(new Dimension(1200, 800));

    data = Data.getData();
    data.init();
    
		//final MyTableModel myModel = new MyTableModel();
		final JTable table = new JTable(myModel);
		table.setRowSorter(new TableRowSorter<TableModel>(myModel));
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		setUpEditColumn(table);

		JPanel p = new JPanel(new FlowLayout());
    JButton addButton = new JButton(bundle.getString("add_new_${pojo.getDeclarationName()}"));
    JButton editButton = new JButton(bundle.getString("edit_${pojo.getDeclarationName()}"));
		JButton deleteButton = new JButton(bundle.getString("delete_${pojo.getDeclarationName()}"));
		JButton refreshButton = new JButton(bundle.getString("refresh_${pojo.getDeclarationName()}"));

    p.add(addButton);
    p.add(editButton);
		p.add(deleteButton);
		p.add(refreshButton);

		<#if hasSet>
		JButton editCrossButton = new JButton(bundle.getString("edit_cross_${pojo.getDeclarationName()}"));
		p.add(editCrossButton);
		</#if>	

		JScrollPane scroller = new JScrollPane();
		scroller.setViewportView(table);
		scroller.setViewportBorder(BorderFactory.createLineBorder(Color.black));
		add(scroller, BorderLayout.CENTER);
		add(p, BorderLayout.SOUTH);
        addButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                TopLevel.frame.setGlassPane(new ${pojo.getDeclarationName()}AddEdit(${pojo.getDeclarationName()}TableList.this,
                    new ${pojo.getDeclarationName()}()));
                TopLevel.frame.getGlassPane().setVisible(true);
            
            /*
                ${pojo.getDeclarationName()} value = new ${pojo.getDeclarationName()}();
                value.setCreateTime(new Date());
                value.setModifyTime(new Date());
                data.create${pojo.getDeclarationName()}(value);
                JOptionPane.showMessageDialog(null, bundle.getString("add_success"));
                myModel.fireTableDataChanged();
                // table.updateUI();
                */
            }
        });
        editButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                if (table.getSelectedRow() < 0)
                {
                    return;
                }
                int selection = table.convertRowIndexToModel(table
                    .getSelectedRow());
                TopLevel.frame.setGlassPane(new ${pojo.getDeclarationName()}AddEdit(${pojo.getDeclarationName()}TableList.this,
                    data.get${pojo.getDeclarationName()}s().get(selection)));
                TopLevel.frame.getGlassPane().setVisible(true);
            
            /*
                ${pojo.getDeclarationName()} value = new ${pojo.getDeclarationName()}();
                value.setCreateTime(new Date());
                value.setModifyTime(new Date());
                data.create${pojo.getDeclarationName()}(value);
                JOptionPane.showMessageDialog(null, bundle.getString("add_success"));
                myModel.fireTableDataChanged();
                // table.updateUI();
                */
            }
        });
		deleteButton.addActionListener(new ActionListener()
		{
		    public void actionPerformed(ActionEvent ae)
		    {
				if (table.getSelectedRow() < 0)
				{
				    return;
				}
				int selection = table.convertRowIndexToModel(table
					.getSelectedRow());
				Object[] messageArguments = {
					new Long(data.get${pojo.getDeclarationName()}s().get(selection).getId())	
					};
				MessageFormat formatter = new MessageFormat("");
				formatter.setLocale(currentLocale);
				formatter.applyPattern(bundle.getString("confirm_delete"));
				String output = formatter.format(messageArguments);		
				int res = JOptionPane.showConfirmDialog(null, output);

				if (res == JOptionPane.YES_OPTION)
				{
				    data.delete${pojo.getDeclarationName()}(data.get${pojo.getDeclarationName()}s().get(selection));
				    data.flush();
				    myModel.fireTableDataChanged();
				    // table.updateUI();
				}
		    }
		});
		refreshButton.addActionListener(new ActionListener()
		{
		    public void actionPerformed(ActionEvent ae)
		    {
				// data.clear();
				myModel.fireTableDataChanged();
		    }
		});
		<#if hasSet>
		editCrossButton.addActionListener(new ActionListener()
		{
		    public void actionPerformed(ActionEvent ae)
		    {
				if (table.getSelectedRow() < 0)
				{
				    return;
				}
				int selection = table.convertRowIndexToModel(table
					.getSelectedRow());
				${pojo.getDeclarationName()} val = data.get${pojo.getDeclarationName()}s().get(
					selection);
				TopLevel.frame.setGlassPane(new ${SetClassName}CrossEdit(val));
				TopLevel.frame.getGlassPane().setVisible(true);
		    }
		});
		</#if>	
    }

    public void updateUI()
    {
		super.updateUI();
		if (myModel != null)
		{
		    myModel.fireTableDataChanged();
		}
    }

    public void setUpEditColumn(JTable table)
    {
<#assign x = 0> 			
<#foreach field in pojo.getAllPropertiesIterator()>
<#if !pojo.getJavaTypeName(field,false).equals("Set") >

<#if (field.type.toString().indexOf("ManyToOneType") > 0) >
		// Set up the editor for the ${pojo.getJavaTypeName(field,false)} cells.
		TableColumn tableColumn${x} = table.getColumnModel().getColumn(${x});
		JComboBox comboBox${x} = new JComboBox();
		for (${pojo.getJavaTypeName(field,false)} item : data.get${pojo.getJavaTypeName(field,false)}s())
		{
		    comboBox${x}.addItem(item/*.getName()*/);
		}
		tableColumn${x}.setCellEditor(new DefaultCellEditor(comboBox${x}));
</#if> 

<#assign x = x+1> 			
</#if> 
</#foreach>			 

    DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
    renderer.setToolTipText(bundle.getString("click_to_edit"));

    table.setDefaultRenderer(Date.class, new DateRenderer(true));
    }

    class MyTableModel extends AbstractTableModel
    {
		private String[] columnNames = {
<#foreach field in pojo.getAllPropertiesIterator()>
<#if !pojo.getJavaTypeName(field,false).equals("Set") >
"${field.name}"<#if field_has_next >,
</#if> 
</#if> 
</#foreach>			 
	};

	public int getColumnCount()
	{
	    return columnNames.length;
	}

	public int getRowCount()
	{
	    return data.get${pojo.getDeclarationName()}s().size();
	}

	public String getColumnName(int col)
	{
	    return columnNames[col];
	}

	public Object getValueAt(int row, int col)
	{
	    ${pojo.getDeclarationName()} value = data.get${pojo.getDeclarationName()}s().get(row);
	    switch (col)
	    {
<#assign x = 0> 			
<#foreach field in pojo.getAllPropertiesIterator()>
<#if !pojo.getJavaTypeName(field,false).equals("Set") >
      case ${x}:
        return value.${pojo.getGetterSignature(field)}();
<#assign x = x+1>       
</#if> 
</#foreach>			 
		    }
		    return null;
		}
	
	/*
	 * JTable uses this method to determine the default renderer/ editor for
	 * each cell.
	 */
	@SuppressWarnings("unchecked")
	public Class getColumnClass(int c)
	{
	    switch (c)
	    {
<#assign x = 0> 			
<#foreach field in pojo.getAllPropertiesIterator()>
<#if !pojo.getJavaTypeName(field,false).equals("Set") >
			case ${x}:
			<#if pojo.getJavaTypeName(field, false).equals("long") >
				return Long.class; 
			<#else>	
				return ${pojo.getJavaTypeName(field, false)}.class;
			</#if> 
<#else> 
      case ${x}:
      <#if pojo.getJavaTypeName(field, false).equals("long") >
        return Long.class; 
      <#else> 
        return ${pojo.getJavaTypeName(field, false)}.class;
      </#if> 
</#if>
<#assign x = x+1>       
</#foreach>			 
	    }
	    return Integer.class;
	}

	/*
	 * Don't need to implement this method unless your table's editable.
	 */
	public boolean isCellEditable(int row, int col)
	{
		switch (col)
		{
<#assign x = 0> 			
<#foreach field in pojo.getAllPropertiesIterator()>
<#if !pojo.getJavaTypeName(field,false).equals("Set") >
			case ${x}:
			<#if pojo.getFieldDescription(field).indexOf("editable") != -1 >
				return true; 
			<#else>	
				return false;
			</#if> 
<#assign x = x+1> 			
</#if> 
</#foreach>			 
		}
		return false;
	}

	/*
	 * Don't need to implement this method unless your table's data can
	 * change.
	 */
	public void setValueAt(Object value, int row, int col)
	{
	    try
	    {
			${pojo.getDeclarationName()} obj = data.get${pojo.getDeclarationName()}s().get(row);
			switch (col)
			{
<#assign x = 0>
<#foreach field in pojo.getAllPropertiesIterator()>
<#if !pojo.getJavaTypeName(field,false).equals("Set") >
			<#if pojo.getFieldDescription(field).indexOf("editable") != -1 >
				case ${x}:
				<#if pojo.getJavaTypeName(field,false).equals("String") >
					obj.set${pojo.getPropertyName(field)}( (String)value );
				</#if> 
				<#if pojo.getJavaTypeName(field,false).equals("long") >
					obj.set${pojo.getPropertyName(field)}( new Long(value.toString()) );
				</#if> 
				<#if pojo.getJavaTypeName(field,false).equals("Date") >
					obj.set${pojo.getPropertyName(field)}( (Date)value );
				</#if> 
				<#if pojo.getJavaTypeName(field,false).equals("Boolean") >
					obj.set${pojo.getPropertyName(field)}( (Boolean)value );
				</#if> 
				<#if pojo.getJavaTypeName(field,false).equals("Long") >
					obj.set${pojo.getPropertyName(field)}( (Long)value );
				</#if> 
				<#if (field.type.toString().indexOf("ManyToOneType") > 0) >
					obj.set${pojo.getPropertyName(field)}( (${pojo.getJavaTypeName(field,false)})value );
        //${pojo.getJavaTypeName(field,false)}
				</#if> 
				break;
			</#if>
<#assign x = x+1>
</#if> 
</#foreach>			 
				}
				data.flush();
		    }
		    catch (Exception e)
		    {
				JOptionPane.showMessageDialog(null, bundle.getString("please_input"));
		    }
		}
    }

    /**
     * Create the GUI and show it. For thread safety, this method should be
     * invoked from the event-dispatching thread.
     */
    private static void createAndShowGUI()
    {
		// Create and set up the window.
		JFrame frame = new JFrame(bundle.getString("${pojo.getDeclarationName()}_management"));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	
		// Create and set up the content pane.
		${pojo.getDeclarationName()}TableList newContentPane = new ${pojo.getDeclarationName()}TableList();
		newContentPane.setOpaque(true); // content panes must be opaque
		frame.setContentPane(newContentPane);
	
		// Display the window.
		frame.pack();
		frame.setVisible(true);
    }
	
    public static void main(String[] args)
    {
		// Schedule a job for the event-dispatching thread:
		// creating and showing this application's GUI.
		javax.swing.SwingUtilities.invokeLater(new Runnable()
		{
			public void run()
			{
				// read from file MessagesBundle_en_us.properties
				bundle = ResourceBundle.getBundle("MessagesBundle", Locale.CHINA);
				System.out.println("Message in " + Locale.US + ": " + bundle.getString("greeting"));		
				createAndShowGUI();
			}
		});
	}
}